
#ifndef Lily_ui
#define Lily_ui

#ifdef __cplusplus
extern "C"
{
#endif

#define to_voidf(x) (void *)(*((int32_t *)&x))
#define to_void(x) ((void *)(x))
#define void_to_int(p) ((int32_t)(p))
#define assign_f_from_void(f, p) (*((int32_t *)&f) = (int32_t)p)
#define cast(x, type) ((type)(x))

#define KeepHijack 1
#define Lily_cmd_do_not_notify 0x0100 // return code from shell_do

#define shell_dos_done 0x10 // return from shell_do_xxx showing it deal the work

#define lily_do_stack_len 8
#define invoke_listener _cmd_done_listener_stack_top--
#define current_listener _cmd_done_listener[_cmd_done_listener_stack_top - 1]
#define have_listener _cmd_done_listener_stack_top

	extern char _stack_top;
	extern Tasks_def _cmd_done_listener[];
	extern char _cmd_done_listener_stack_top;

	extern char rx[];
	extern unsigned char ri, hi;
	extern int32_t _cmd_queue_in_waiting, _lily_is_busy;
#ifndef TX_len
#define TX_len 128
#endif

	extern LilyUI_t lily_ui;
	// extern Li_List sch_items; // List<Schedule_item_t>

	int32_t _get_cmd_from_rx(void);
	int32_t lily_do(char *rx);
	void add_hijack(Cmdline_def call_back);
	void add_listener(Tasks_def f);
	int32_t notify_listener(void);

	int32_t search_cmd_in_Lily_ui(const char *item);
	int32_t search_fun_in_Lily_ui(const char *item);
	int32_t search_var_in_Lily_ui(const char *item);

	int32_t _test_redirection_output_to_var(char *rx);

	int32_t cmd_help(int32_t a, char **b);

	int32_t cmd_delete(int32_t n, char **arg);

	int32_t cmd_reduction_memory(int32_t n, char **arg);

	int32_t cmd_whos(int32_t n, char **arg);

	int32_t cmd_delay(int32_t n, char **arg);

	int32_t cmd_type(int32_t n, char *arg[]);

	int32_t cmd_schedule(int32_t n, char *arg[]);

	/* Cmdline API */
	int32_t public_a_cmd_link(const char *name, Cmdline_def link);
	int32_t public_a_cmd_link_doc(const char *name, Cmdline_def link, const char *help_doc);
	int32_t remove_cmd_by_str(char *cmd);
	/* Fun API */
	int32_t public_a_fun_link_n(const char *name, void *link, char n);
	int32_t public_a_fun_link_int(const char *name, void *link, char n);
	int32_t remove_fun_by_str(char *cmd);

	int32_t joint_args(int32_t n, char **args);

	int32_t cmd_hijacker_wait_key(int32_t n, char **s);
	int32_t cmd_echo(int32_t n, char **arg);
	int32_t cmd_hijack_sleep(int32_t n, char **arg);


#define li_vars ((Var)(lily_ui.vars->content))
#define li_cmds ((Cmd)(lily_ui.cmds->content))
#define li_funs ((Fun)(lily_ui.funs->content))

	int32_t public_a_var_ref(const char *name, void *link, char type);
	int32_t public_a_new_var(char *name, char type, void *val);
	int32_t public_new_vars_array(char *name, char type, void *val, int32_t len);
	int32_t public_new_vars_array_by_string(char *name, char type, char *val, int32_t len);

	void *get_value_of_var(Var var, int32_t at);
	int32_t set_value_of_var(Var var, int32_t at, void *val);
	int32_t delete_a_var(Var var);

	int32_t str_collection(int32_t n, char *arg[]);
	int32_t cmd_call(int32_t n, char *arg[]);

	void freeze_cmd_stream(void);
	void resume_cmd_stream(void);

	extern Pipe pipe_out_to_str_var;


#ifdef __cplusplus
}
#endif

#endif
